﻿using MySql.Data.MySqlClient;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MachineInfoModule;

namespace MQ
{
    public class MysqlAdpt : ISender<MachineInfo, String>
    {
        private Dictionary<String,String> destServConnStr = new Dictionary<String,String>();

        public void RegisterMQ(String destIdent,String connStr)
        {
            if (!destServConnStr.Keys.Contains(destIdent))
            {
                destServConnStr.Add(destIdent, connStr);
            }
        }

        private void tranMsg(MySqlCommand ins, MySqlCommand upd, MySqlCommand chk, String type, String id, String Val)
        {
            ins.Parameters["?type"].Value = type;
            chk.Parameters["?type"].Value = type;           
            //upd.Parameters["?type"].Value = type;

            ins.Parameters["?id"].Value = id;
            //upd.Parameters["?id"].Value = id;

            ins.Parameters["?val"].Value = Val;
            //upd.Parameters["?val"].Value = Val;
            chk.Parameters["?val"].Value = Val;

            MySqlDataReader rd = chk.ExecuteReader();
            var isExists = rd.HasRows;
            rd.Close();
            if (!isExists)
                ins.ExecuteNonQuery();

        }
        private void tranMapMsg<T>(MySqlCommand ins, MySqlCommand upd, MySqlCommand chk, String kind, T map) where T:IDictionary
        {
            foreach (var k in map.Keys)
            {
                tranMsg(ins, upd, chk, k.ToString(), kind, map[k].ToString());
            }
        }
        private void insert_machine_info(MySqlConnection myCon, MachineInfo msg)
        {
            if (myCon.State != System.Data.ConnectionState.Open)
                myCon.Open();
            MySqlTransaction tran = myCon.BeginTransaction();
            MySqlCommand insertCmd = myCon.CreateCommand();
            MySqlCommand existsCheckCmd = myCon.CreateCommand();
            MySqlDataReader rd = null;
            Boolean isExists = false;
            try
            {
                insertCmd.CommandType = System.Data.CommandType.Text;
                insertCmd.CommandText = "insert into it.MachineInfo(host_name,user_name,info_type,info_id,info_value) values (?host,?user,?type,?id,?val)";
                insertCmd.Parameters.Add("?host", MySqlDbType.VarChar);
                insertCmd.Parameters.Add("?user", MySqlDbType.VarChar);
                insertCmd.Parameters.Add("?type", MySqlDbType.VarChar);
                insertCmd.Parameters.Add("?id", MySqlDbType.VarChar);
                insertCmd.Parameters.Add("?val", MySqlDbType.VarChar);

                existsCheckCmd.CommandType = System.Data.CommandType.Text;
                existsCheckCmd.CommandText = "select autoid from it.MachineInfo where host_name = ?host and user_name = ?user and info_type = ?type and info_value = ?val";
                existsCheckCmd.Parameters.Add("?host", MySqlDbType.VarChar);
                existsCheckCmd.Parameters.Add("?user", MySqlDbType.VarChar);
                existsCheckCmd.Parameters.Add("?type", MySqlDbType.VarChar);
                existsCheckCmd.Parameters.Add("?val", MySqlDbType.VarChar);

                insertCmd.Parameters["?host"].Value = msg.HOST_Name;
                insertCmd.Parameters["?user"].Value = msg.User;

                existsCheckCmd.Parameters["?host"].Value = msg.HOST_Name;
                existsCheckCmd.Parameters["?user"].Value = msg.User;

               
                int idx = 0;
                if (msg.CPUs_Infos != null && msg.CPUs_Infos.Count > 0)
                {
                    foreach(var cpu in msg.CPUs_Infos)
                    {
                        tranMapMsg(insertCmd, null, existsCheckCmd, "CPU" + idx.ToString(),cpu);
                        idx++;
                    }                    
                }
                else if (msg.CPU_SN != null)
                {
                    idx = 0;
                    insertCmd.Parameters["?type"].Value = "CPU_SN";
                    existsCheckCmd.Parameters["?type"].Value = "CPU_SN";

                    msg.CPU_SN.ForEach(sn =>
                    {
                        insertCmd.Parameters["?id"].Value = "CPU" + idx.ToString();
                        insertCmd.Parameters["?val"].Value = sn;

                        existsCheckCmd.Parameters["?val"].Value = sn;
                        idx++;
                        rd = existsCheckCmd.ExecuteReader();
                        isExists = rd.HasRows;
                        rd.Close();
                        if (!isExists)
                            insertCmd.ExecuteNonQuery();
                    });
                }

                if (msg.HDs_Infos != null && msg.HDs_Infos.Count > 0)
                {
                    idx = 0;
                    foreach (var hd in msg.HDs_Infos)
                    {
                        tranMapMsg(insertCmd, null, existsCheckCmd, "HD" + idx.ToString(), hd);
                        idx++;
                    }
                }
                else if (msg.HD_SN != null)
                {
                    idx = 0;
                    insertCmd.Parameters["?type"].Value = "HD_SN";
                    existsCheckCmd.Parameters["?type"].Value = "HD_SN";
                    msg.HD_SN.ForEach(sn => {
                        insertCmd.Parameters["?id"].Value = "HardDisk" + idx.ToString();
                        insertCmd.Parameters["?val"].Value = sn;

                        existsCheckCmd.Parameters["?val"].Value = sn;
                        idx++;
                        rd = existsCheckCmd.ExecuteReader();
                        isExists = rd.HasRows;
                        rd.Close();
                        if (!isExists)
                            insertCmd.ExecuteNonQuery();
                    });
                }

                if (msg.NETCARD_MAC != null)
                {
                    idx = 0;
                    insertCmd.Parameters["?type"].Value = "MAC";
                    existsCheckCmd.Parameters["?type"].Value = "MAC";
                    msg.NETCARD_MAC.ForEach(mac => {
                        insertCmd.Parameters["?id"].Value = "NetCard" + idx.ToString();
                        insertCmd.Parameters["?val"].Value = mac;

                        existsCheckCmd.Parameters["?val"].Value = mac;
                        idx++;
                        rd = existsCheckCmd.ExecuteReader();
                        isExists = rd.HasRows;
                        rd.Close();
                        if (!isExists)
                            insertCmd.ExecuteNonQuery();
                    });
                }

                tran.Commit();
            }
            catch (Exception e)
            {
                tran.Rollback();
                throw e;
            }
            finally
            {
                insertCmd.Dispose();
                tran.Dispose();
                myCon.Close();
                myCon.Dispose();
            }
        }

        public void Send(string destIdent, MachineInfo msg)
        {
            if (destServConnStr.Keys.Contains(destIdent))
            {
                try
                {
                    MySqlConnection myCon = new MySqlConnection(destServConnStr[destIdent]);
                    insert_machine_info(myCon, msg);
                }
                catch (Exception e)
                {
                    throw new Exception("消息发送失败！",e);
                }
            }
            else
            {
                throw new Exception("未注册的消息目标");
            }
        }
    }
}
